//==============================================================================
//
//         DDouble - the double number class in the ofc-library
//
//               Copyright (C) 2003  Dick van Oudheusden
//  
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//==============================================================================
// 
//  $Date: 2005-02-05 06:25:37 $ $Revision: 1.7 $
//
//==============================================================================

#include "ofc/DDouble.h"

#include <limits.h>
#include <stdlib.h>

#if _INTERFACE_

#include "ofc/config.h"

#include "ofc/DComparable.h"
#include "ofc/DTextable.h"
#include "ofc/DDatable.h"
#include "ofc/DParsable.h"

#include "ofc/DText.h"
#include "ofc/DData.h"

// The Double class implements a number of methods for storing and manipulating double numbers.

@interface DDouble : Object <DComparable,DTextable,DDatable,DParsable>
{
@private
  double       _double;
}

#endif




@implementation DDouble


//// Constructors

//
// Initialise to number zero
//
// @return the object
//

- (DDouble *) init
{
  [super init];

  _double = 0.0;
  
  return self;
}

//
// Initialise to a number
//
// @param number   the number
//
// @return the object
//

- (DDouble *) init :(double) number
{
  [self init];

  _double = number;

  return self;
}



//// Member methods

//
// Get the double
//
// @return the double number
//

- (double) get
{
  return _double;
}

//
// Set the double number
//
// @param number  the double number
//
// @return the object
//

- (DDouble *) set :(double) number
{
  _double = number;

  return self;
}


//// Comparable protocol

//
// Compare two double objects
//
// @param other    the object to compare with
//
// @return the result of the comparison (-1,0,1)
//

- (int) compare :(DDouble *) other
{
  if (self != other)
  {
    double d = [other get];
    
    if (_double < d)
    {
      return -1;
    }
    else if (_double > d)
    {
      return 1;
    }
    else
    {
      return 0;
    }
  }
  else
  {
    return 0;
  }
}


//// Textable protocol

//
// Return a text string with the double
//
// @return a (new) text string with the number
//

- (DText *) toText
{
  return [[[DText alloc] init] format :"%g",_double];
}


//// Datable protocol

//
// Return a data string with the double
//
// @return a (new) data string
//

- (DData *) toData
{
  return [[DData alloc] init :(unsigned char *)&_double :sizeof(_double)];
}


//// Parsable protocol

//
// Parse a string to set the double
//
// @param cstr     the string to be parsed (moved to first non-parsable char)
// 
// @return the result (0, ERANGE, ENODATA)
//

- (int) fromString :(char **) cstr
{
  int     result = 0;
  double  number = 0.0;
  char   *src    = *cstr;

  number = strtod(*cstr, cstr);

  if (src == *cstr)
  {
    result = ENODATA;
  }
  else if (errno == ERANGE)
  {
    result = ERANGE;
  }
  else
  {
    _double = number;
  }

  return result;
}

@end

/*==========================================================================*/

